#!/bin/bash
# ============================================================
# 一键生成自签名 CA + 服务器 + 客户端证书（统一 PEM 格式，标准化）
# ============================================================

# -----------------------
# 配置变量
# -----------------------
# 通用证书字段
C="CN"
ST="Jiangsu"
L="Nanjing"
O="Nanjing TT Information Technology Co., Ltd."

# 域名 / CN
CA_CN="TakeTo MQTT Root CA"
SERVER_CN="mqtt.taketo.cc"
CLIENT_CN="mqtt_client_01"

# 有效期（天）
DAYS_CA=36525
DAYS_SERVER=36525
DAYS_CLIENT=36525

# 证书目录
CERT_DIR="./certs"

# -----------------------
# 创建目录 & 清理旧文件
# -----------------------
mkdir -p "$CERT_DIR"
cd "$CERT_DIR" || exit
rm -f rootCA.* server.* client.* *.srl openssl-server.cnf

# =======================
# 1️⃣ 生成自签名 CA
# =======================
echo "===== Generating CA ====="
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days "$DAYS_CA" \
    -out rootCA.pem \
    -subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/CN=${CA_CN}"

# =======================
# 2️⃣ 生成服务器证书（带 SAN）
# =======================
echo "===== Generating Server Certificate ====="
openssl genrsa -out server.key 2048

cat > openssl-server.cnf <<EOF
[ req ]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext
x509_extensions    = v3_req
prompt             = no

[ req_distinguished_name ]
C  = ${C}
ST = ${ST}
L  = ${L}
O  = ${O}
CN = ${SERVER_CN}

[ req_ext ]
subjectAltName = @alt_names

[ v3_req ]
subjectAltName = @alt_names
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth

[ alt_names ]
DNS.1 = ${SERVER_CN}
IP.1 = 127.0.0.1
EOF

# 生成 CSR
openssl req -new -key server.key -out server.csr -config openssl-server.cnf
# CA 签发证书
openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial \
    -out server.pem -days "$DAYS_SERVER" -sha256 -extensions v3_req -extfile openssl-server.cnf

echo "Server certificate SAN:"
openssl x509 -in server.pem -text -noout | grep -A1 "Subject Alternative Name"

# =======================
# 3️⃣ 生成客户端证书（不加密私钥）
# =======================
echo "===== Generating Client Certificate ====="
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
    -subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/CN=${CLIENT_CN}"

openssl x509 -req -in client.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial \
    -out client.pem -days "$DAYS_CLIENT" -sha256

# =======================
# 4️⃣ 生成目录结构说明
# =======================
echo "===== Certificates generated ====="
echo "Directory and files structure:"
echo "
$CERT_DIR/
├─ openssl-server.cnf # 服务器生成配置文件
├─ rootCA.srl         # CA 序列号文件
├─ rootCA.key         # CA 私钥
├─ rootCA.pem         # CA 证书
├─ server.key         # 服务器私钥
├─ server.csr         # 服务器证书请求
├─ server.pem         # 服务器证书
├─ client.key         # 客户端私钥
├─ client.csr         # 客户端证书请求
├─ client.pem         # 客户端证书
"

# =======================
# 5️⃣ MQTT 客户端示例
# =======================
echo ""
echo "MQTT Client example:"
echo "mqttx sub -t 't/1' -h ${SERVER_CN} -p 8883 \\"
echo "  --protocol mqtts \\"
echo "  --ca ./certs/rootCA.pem \\"
echo "  --cert ./certs/client.pem \\"
echo "  --key ./certs/client.key \\"
echo "  -u test -P test"
